/******************************************************************************

    Simple Authentication and Authorisation System (SAAS)

    group-group_info_with_members_by_groupname.c

    Copyright (C) 2011  Josh Goes


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    If you require a mailing address for this software, please send your
    mail to the following address:
        SAAS
        GPO Box 2973
        BRISBANE QLD 4001
        AUSTRALIA

******************************************************************************/


#include "saas-build.h"

#include <stdint.h>
#include <stdlib.h>
#include <string.h>


uint16_t saas_group_info_with_members_by_groupname( saas_t *inst , const char *groupname , saas_group_info_t **group_info )
{
	uint16_t  pkt_len = SAAS_MAX_PKT_LEN;
	uint8_t      *pkt = malloc( pkt_len );
	uint16_t      ret;
	uint32_t      trans_id;

	logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): starting" );
	if ( pkt == NULL )
	{
		logm( inst , LOG_CRIT , "saas_group_info_with_members_by_groupname(): error allocating memory for drafting request packet" );
		return SAAS_OP_MEM_ERROR;
	}

	int idx;
	for ( idx = 0 ; idx < SAAS_MAX_NUM_HOSTS ; idx++ )
	{
		if ( inst->hosts[idx].type == 0 )
			continue;
		logh( inst , LOG_DEBUG , &inst->hosts[idx] , "saas_group_info_with_members_by_groupname(): attempting to connect to host: " );

		// generate a transmit packet for transmission.
		logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): compiling GROUP_BY_GID REQUEST packet." );
		ret = pkt_req_group_info_with_members_by_groupname( inst , &trans_id , pkt , &pkt_len , (uint8_t *) groupname , strlen( groupname ) );
		if ( ret != SAAS_OP_SUCCESS )
		{
			logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): error drafting request packet" );
			free( pkt );
			return ret;
		}

		// encrypt the packet.
		logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): encrypting packet ready for transmission." );
		pkt_encrypt( inst , pkt , &pkt_len );

		// now send it out and receive a response.
		logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): transmitting packet and waiting for response." );
		ret = pkt_transceive( inst , pkt , &pkt_len , &inst->hosts[idx] );
		if ( ret != SAAS_OP_SUCCESS )
		{
			logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): error transmitting/receiving packet: (%d) %s" , ret , saaserror( ret ) );
			continue;
		}

		// decrypt the response.
		logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): attempting to decrypt received packet." );
		ret = pkt_decrypt( inst , pkt , pkt_len );
		if ( ret != SAAS_OP_SUCCESS )
		{
			logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): decryption failed with code: (%d) %s" , ret , saaserror( ret ) );
			free( pkt );
			return SAAS_OP_DECRYPT_ERROR;
		}

		// unpack the response packet.
		logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): verifying response and extracting response data" );
		ret = pkt_resp_group_info( inst , trans_id , pkt , pkt_len , group_info );
		logm( inst , LOG_DEBUG , "saas_group_info_with_members_by_groupname(): result of request: (%d) %s" , ret , saaserror( ret ) );
		switch ( ret )
		{
			// errors that are permanent, not temporary.
			case SAAS_OP_SUCCESS:
			case SAAS_OP_GROUP_NOT_FOUND:
				free( pkt );
				return ret;
		}
	}
	logm( inst , LOG_WARNING , "saas_group_info_with_members_by_groupname(): attempted all hosts with no success." );
	free( pkt );
	return SAAS_OP_NO_HOSTS;
}

